package chances.system.operator.web;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Validation;
import javax.validation.ValidatorFactory;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import chances.system.json.JsonResponse;
import chances.system.log.entity.ActionLog;
import chances.system.operator.entity.EnumData;
import chances.system.operator.entity.Oplog;
import chances.system.operator.repo.EnumDataRepository;
import chances.webui.model.Tree;
import chances.webui.model.TreeNode;

/**
* @author panzx
* @version 创建时间：2017年9月14日 下午3:33:13
*/
@RestController
public class EnumDataController extends BaseController {
    ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
    private static final Logger logger = LoggerFactory.getLogger(EnumDataController.class);
    @Autowired
    EnumDataRepository enumDataRepository;

    @ActionLog(operateType = Oplog.OP_ADD, objName = "EnumData", desc = "添加修改基础数据'{name}'")
    @RequestMapping(path = "/sys/enumData/save", method = RequestMethod.POST)
    public JsonResponse saveEnumData(HttpServletRequest request, @RequestBody EnumDataModel model) {
        JsonResponse response = new JsonResponse();
        EnumData enumData = model.getEnumData();
        String name = enumData.getName();
        String code = enumData.getCode();
        if (name != null && name != "" && name.indexOf(" ") != -1) {
            response.setErrorResult("数据名称不能含有空格！");
            return response;
        }
        if (code != null && code != "" && code.indexOf(" ") != -1) {
            response.setErrorResult("数据编码不能含有空格！");
            return response;
        }
        try {
            if (enumData.getParentId() == null || enumData.getParentId() == 1001) {
                if (enumData.getCode() == "") {
                    response.setErrorResult("一级目录数据编码不能为空！");
                    return response;
                }
                if (enumData.getId() != null) {
                    if (StringUtils.isNotBlank(enumData.getCode())) {
                        List<EnumData> enumDatasByCode = enumDataRepository
                                .findByCode(enumData.getCode());
                        if (enumDatasByCode != null && enumDatasByCode.size() > 0) {
                            if (!(enumData.getId().equals(enumDatasByCode.get(0).getId()))) {
                                response.setErrorResult("数据编码重复！");
                                return response;
                            }
                        }
                    }
                    List<EnumData> enumDatasByName = enumDataRepository
                            .findByName(enumData.getName());
                    if (enumDatasByName != null && enumDatasByName.size() > 0) {
                        if (!(enumData.getId().equals(enumDatasByName.get(0).getId()))) {
                            response.setErrorResult("数据名称重复！");
                            return response;
                        }
                    }
                    EnumData dbEnumData = enumDataRepository.findById(enumData.getId());
                    if (dbEnumData != null) {
                        enumData = (EnumData) copyProperties(enumData, dbEnumData);
                    }
                } else {
                    if (StringUtils.isNotBlank(enumData.getCode())) {
                        List<EnumData> enumDatasByCode = enumDataRepository
                                .findByCode(enumData.getCode());
                        if (enumDatasByCode != null && enumDatasByCode.size() > 0) {
                            response.setErrorResult("数据编码重复！");
                            return response;
                        }
                    }
                    List<EnumData> enumDatasByName = enumDataRepository
                            .findByName(enumData.getName());
                    if (enumDatasByName != null && enumDatasByName.size() > 0) {
                        response.setErrorResult("数据名称重复！");
                        return response;
                    }
                }
            } else {
                if (enumData.getId() != null) {
                    List<EnumData> enumDatasByParentId = enumDataRepository
                            .findByParentId(enumData.getParentId());
                    List<EnumData> enumDatasByCode = enumDataRepository
                            .findByCode(enumData.getCode());
                    List<EnumData> nameFindByParentId = enumDataRepository
                            .nameFindByParentId(enumData.getParentId());
                    for (int i = 0; i < enumDatasByCode.size(); i++) {
                        if (StringUtils.isNotBlank(enumData.getCode())) {
                            if (enumData.getCode().equals(enumDatasByCode.get(i).getCode())) {
                                if (!enumData.getId().equals(enumDatasByCode.get(i).getId())) {
                                    response.setErrorResult("数据编码重复！");
                                    return response;
                                }
                            }
                        }
                    }
                    for (int i = 0; i < enumDatasByParentId.size(); i++) {
                        if (enumData.getName().equals(nameFindByParentId.get(i).getName())) {
                            if (!enumData.getId().equals(nameFindByParentId.get(i).getId())) {
                                response.setErrorResult("数据名称重复！");
                                return response;
                            }
                        }
                    }
                    EnumData dbEnumData = enumDataRepository.findById(enumData.getId());
                    if (dbEnumData != null) {
                        enumData = (EnumData) copyProperties(enumData, dbEnumData);
                    }
                } else {
                    List<EnumData> enumDatasByParentId = enumDataRepository
                            .findByParentId(enumData.getParentId());
                    List<EnumData> enumDatasByCode = enumDataRepository
                            .findByCode(enumData.getCode());
                    List<EnumData> nameFindByParentId = enumDataRepository
                            .nameFindByParentId(enumData.getParentId());
                    for (int i = 0; i < enumDatasByCode.size(); i++) {
                        if (StringUtils.isNotBlank(enumData.getCode())) {
                            if (enumData.getCode().equals(enumDatasByCode.get(i).getCode())) {
                                response.setErrorResult("数据编码重复！");
                                return response;
                            }
                        }
                    }
                    for (int i = 0; i < enumDatasByParentId.size(); i++) {
                        if (enumData.getName().equals(nameFindByParentId.get(i).getName())) {
                            response.setErrorResult("数据名称重复！");
                            return response;
                        }
                    }
                }
            }
        } catch (Exception e) {
            logger.error(e.toString(), e);
            response.setErrorResult(e.getMessage());
            return response;
        }
        enumDataRepository.save(enumData);
        return response;
    }

    @ActionLog(operateType = Oplog.OP_DELETE, objName = "EnumData", desc = "删除基础数据'{name}'")
    @RequestMapping(value = "/sys/enumData/delete/{id}", method = RequestMethod.GET)
    public @ResponseBody JsonResponse delete(HttpServletRequest request,
            @PathVariable("id") Long id, Model model) {
        JsonResponse response = new JsonResponse();
        List<EnumData> enumDatas = enumDataRepository.findByParentId(id);
        if (enumDatas != null && enumDatas.size() > 0) {
            response.setErrorResult("该节点存在子节点，不能删除！");
            return response;
        } else {
            enumDataRepository.delete(id);
        }
        return response;
    }

    @RequestMapping(path = "/sys/enumData/tree", method = RequestMethod.GET)
    public List<Map<String, Object>> getEnumDataTree(HttpServletRequest httpServletRequest) {
        List<EnumData> EnumDatas = enumDataRepository.findAvaliableEnumData();
        List<TreeNode<EnumData>> nodes = EnumDatas.stream().map(s -> {
            return createEnumDataNode(s);
        }).collect(Collectors.toList());
        Tree<EnumData> enumDataTree = new Tree<EnumData>(nodes);
        List<Map<String, Object>> map = createNodeListMap(enumDataTree.getRootNodes());
        return map;
    }

    public TreeNode<EnumData> createEnumDataNode(EnumData EnumData) {
        TreeNode<EnumData> node = new TreeNode<EnumData>();
        node.setEntry(EnumData);
        node.setTitle(EnumData.getName());
        node.setId(EnumData.getId().toString());
        if (EnumData.getParentId() != null) {
            node.setParentId(EnumData.getParentId().toString());
        }
        return node;
    }

    public List<Map<String, Object>> createNodeListMap(List<TreeNode<EnumData>> childrens) {
        List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
        if (!childrens.isEmpty()) {
            for (TreeNode<EnumData> children : childrens) {
                list.add(createNodeMap(children));
            }
        }
        return list;
    }

    public Map<String, Object> createNodeMap(TreeNode<EnumData> node) {
        HashMap<String, Object> map = new HashMap<String, Object>();
        map.put("id", node.getId());
        map.put("text", node.getTitle());
        map.put("children", createNodeListMap(node.getChildren()));
        return map;
    }
}
